package cdu.sl.common.utils;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


@Component
public class AliyunOSSOperator {

    @Autowired
    private AliyunOSSProperties aliyunOSSProperties;

    public AliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) {
        this.aliyunOSSProperties = aliyunOSSProperties;
    }

    public AliyunOSSOperator() {
    }

    /**
     * 上传文件到Bucket
     * @param content 文件转字节数组
     * @param originalFilename 原文件名称
     * @return 图片URL地址
     * @throws Exception
     */
    public String upload(byte[] content, String originalFilename) throws Exception {
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        String region = aliyunOSSProperties.getRegion();
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 填写Object完整路径，例如202406/1.png。Object完整路径中不能包含Bucket名称。
        //获取当前系统日期的字符串,格式为 yyyy/MM
        String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
        //生成一个新的不重复的文件名
        String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = dir + "/" + newFileName;

        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
        } finally {
            ossClient.shutdown();
        }

        return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;
    }



    /**
     * 列出指定文件夹中的所有图片URL
     * @param folderPath 文件夹路径，例如"2025/04"
     * @return 图片URL列表
     * @throws Exception 如果访问OSS出错
     */
    public List<String> listImagesInFolder(String folderPath) throws Exception {
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();
        String region = aliyunOSSProperties.getRegion();

        // 确保文件夹路径以/结尾
        if (!folderPath.endsWith("/")) {
            folderPath = folderPath + "/";
        }

        // 从环境变量中获取访问凭证
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 创建OSSClient实例
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        List<String> imageUrls = new ArrayList<>();

        try {
            // 构建列举文件请求
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
            // 设置前缀，表示要列举指定文件夹下的所有文件
            listObjectsRequest.setPrefix(folderPath);
            // 设置最大返回数量
            listObjectsRequest.setMaxKeys(1000);

            ObjectListing objectListing;
            String nextMarker = null;

            do {
                // 如果上一次查询结果有nextMarker，则继续从nextMarker开始列举
                listObjectsRequest.setMarker(nextMarker);
                // 执行列举请求
                objectListing = ossClient.listObjects(listObjectsRequest);

                // 遍历所有Object
                for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                    // 排除文件夹本身
                    if (!objectSummary.getKey().equals(folderPath)) {
                        String objectUrl = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectSummary.getKey();
                        imageUrls.add(objectUrl);
                    }
                }

                nextMarker = objectListing.getNextMarker();
            } while (objectListing.isTruncated());

        } finally {
            ossClient.shutdown();
        }

        return imageUrls;
    }

}